<template>
	<div>
		<!-- 通话中界面 -->
		<div class="voice-container" v-show="showVoiceCall">
			<div class="remote-avatar">
				<img :src="contactInfo.contactAvatar" alt="对方头像" class="avatar-image">
			</div>

			<div class="local-avatar">
				<img :src="userInfo.avatar" alt="我的头像">
			</div>

			<div class="call-info">
				<div class="caller-name">{{ contactInfo.contactName }}</div>
				<div class="call-status">{{ callTime }}</div>
			</div>

			<div class="voice-wave" v-show="isRemoteSpeaking">
				<div class="wave-bar"></div>
				<div class="wave-bar"></div>
				<div class="wave-bar"></div>
				<div class="wave-bar"></div>
				<div class="wave-bar"></div>
			</div>

			<div class="control-buttons">
				<button class="control-button mute" @click="toggleMute" :class="{ active: isMuted }">
					<img class="fa" :src="isMuted ? '/static/images/phone-slash.svg' : '/static/images/microphone.svg'" />
					<span>{{ isMuted ? '取消静音' : '静音' }}</span>
				</button>
				<button class="control-button speaker" @click="toggleSpeaker" :class="{ active: isSpeakerOn }">
					<img class="fa" :src="isSpeakerOn ? '/static/images/volume-up.svg' : '/static/images/volume-off.svg'"
						alt="" />
					<span>{{ isSpeakerOn ? '关闭扬声器' : '扬声器' }}</span>
				</button>
				<button class="control-button end-call" @click="endCall">
					<img class="fa" src="@/static/images/phone-slash.svg" alt="" />
					<span>挂断</span>
				</button>
			</div>
		</div>

		<!-- 来电界面 -->
		<view id="incoming-call" v-show="showIncomingCall">
			<div class="incoming-call">
				<img :src="contactInfo.contactAvatar" alt="头像" class="caller-avatar">
				<div class="caller-name">{{ contactInfo.contactName }}</div>
				<div class="call-status">语音通话邀请...</div>

				<div class="answer-buttons">
					<div class="decline-call" @click="declineCall">
						<img class="fa" src="@/static/images/phone-slash.svg" alt="" />
					</div>
					<div class="accept-call" @click="acceptCall" v-show="!isSelf">
						<img class="fa" src="@/static/images/phone.svg" alt="" />
					</div>
				</div>
			</div>
		</view>
		<!-- toast提示 -->
		<div class="toast" :class="{ show: showToast, hide: !showToast }">
			<div class="toast-content">
				<p>{{ toastMessage }}</p>
			</div>
		</div>
	</div>
</template>

<script>
	import AgoraRTC from 'agora-rtc-sdk-ng';

	export default {
		name: 'VoiceChat',
		props: {
			channelInfo: {
				type: Object,
				required: true
			},
			userInfo: {
				type: Object,
				required: true
			},
			contactInfo: {
				type: Object,
				required: true
			},
			isSelf: {
				type: Boolean,
				default: false
			}
		},
		data() {
			return {
				showVoiceCall: false,
				showIncomingCall: true,
				showToast: false,
				toastMessage: '',
				isMuted: false,
				isSpeakerOn: false,
				isRemoteSpeaking: false,
				callTimer: null,
				callSeconds: 0,
				client: null,
				localAudioTrack: null,
				srcMuted: '/static/images/microphone.svg'
			};
		},
		mounted() {
			console.log('channel-info', this.channelInfo)
		},
		computed: {
			callTime() {
				const hours = Math.floor(this.callSeconds / 3600);
				const minutes = Math.floor((this.callSeconds % 3600) / 60);
				const secs = this.callSeconds % 60;
				return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
			}
		},
		mounted() {
			this.playRingtone();
		},
		beforeDestroy() {
			this.cleanup();
		},
		methods: {
			// 播放铃声
			playRingtone() {
				console.log("播放来电铃声...");
			},

			// 接听电话
			async acceptCall() {
				await this.joinChannel();
			},

			// 拒接电话
			declineCall() {
				this.showIncomingCall = false;
				console.log("停止铃声");
				console.log("已拒绝语音通话");
				this.$emit('call-action', {
					callerId: "caller",
					status: false,
					timestamp: Date.now(),
					userId: this.userInfo.id,
					type: 'voice'
				});
				this.leaveChannel()
			},

			// 挂断电话
			endCall() {
				this.hangUp(this.userInfo.id);
			},

			// 切换静音
			async toggleMute() {
				this.isMuted = !this.isMuted;
				if (this.localAudioTrack) {
					if (this.isMuted) {
						this.localAudioTrack.setVolume(0);
						console.log("已静音");
					} else {
						this.localAudioTrack.setVolume(this.isSpeakerOn ? 100 : 50);
						console.log("取消静音");
					}
				}
			},

			// 切换扬声器
			async toggleSpeaker() {
				this.isSpeakerOn = !this.isSpeakerOn;
				if (this.localAudioTrack) {
					this.localAudioTrack.setVolume(this.isSpeakerOn ? 100 : 50);
					console.log(this.isSpeakerOn ? "扬声器已开启" : "扬声器已关闭");
				}
			},

			// 用户挂断
			hangUp(userUid) {
				this.showVoiceCall = false;
				console.log("语音通话已结束");
				this.$emit('call-action', {
					callerId: "handelUp",
					status: false,
					timestamp: Date.now(),
					userId: userUid,
					type: 'voice'
				});
				this.stopCallTimer();
				this.leaveChannel();
			},

			// 远程用户接受加入频道
			accept(userUid) {
				this.$emit('call-action', {
					callerId: "caller",
					status: true,
					timestamp: Date.now(),
					userId: userUid,
					type: 'voice'
				});
			},

			// 开始通话计时器
			startCallTimer() {
				this.callTimer = setInterval(() => {
					this.callSeconds++;
				}, 1000);
			},

			// 停止通话计时
			stopCallTimer() {
				if (this.callTimer) {
					clearInterval(this.callTimer);
					this.callTimer = null;
				}
				this.callSeconds = 0;
			},

			// 加入频道
			async joinChannel() {
				const {
					appId,
					channel,
					token
				} = this.channelInfo;
				const userId = this.userInfo.id;

				if (!appId || !channel) {
					console.log("App ID 和频道名不能为空");
					return;
				}

				try {
					this.showToastMessage('正在连接...');

					const devices = await AgoraRTC.getMicrophones();
					if (devices.length === 0) {
						console.log('未找到麦克风设备');
						this.handleJoinError('未找到麦克风设备');
						return;
					}
					console.log("正在初始化客户端...");
					AgoraRTC.setLogLevel(2); // 设置日志级别

					// 创建纯音频客户端
					this.client = AgoraRTC.createClient({
						mode: "rtc",
						codec: "vp8"
					});

					console.log("初始化成功", this.client);
					// 加入频道
					console.log("正在加入频道");
					const uid = await this.client.join(appId, channel, token || null, userId);
					console.log('本地用户ID', uid);
					if(this.isSelf){ // 谁发起就谁先发布流
						await this.publishAudio();
					}
					// 设置事件监听
					this.setupClientEvents();

				} catch (error) {
					console.log(`加入频道失败: ${error.message}`);
					console.error(error);
					this.handleJoinError('获取麦克风权限失败');
					this.stopCallTimer();
				}
			},

			// 设置客户端事件监听
			setupClientEvents() {
				// 用户加入事件
				this.client.on("user-joined", async (user) => {
					console.log(`远程用户 ${user.uid} 加入了频道`);
					await this.publishAudio();
				});

				// 监听用户加入并发布音频流事件
				this.client.on("user-published", async (user, mediaType) => {
					if (mediaType === "audio") {
						await this.client.subscribe(user, mediaType);
						console.log(`远程用户 ${user.uid} 发布了音频流`);

						// 播放远程音频
						user.audioTrack.play();
						// 远程用户发布在显示通话页面
						this.showIncomingCall = false;
						this.showVoiceCall = true;
						this.startCallTimer(); //语音通话开始计时

						// 启用音频等级检测
						this.client.enableAudioVolumeIndicator();

						this.client.on("volume-indicator", (volumes) => {
							volumes.forEach((volume) => {
								this.isRemoteSpeaking = volume.level > 5;
							});
						});

						user.audioTrack.on("mute", () => {
							console.log(`用户 ${user.uid} 没有静音`);
						});

						user.audioTrack.on("unmute", () => {
							console.log(`用户 ${user.uid} 已静音`);
						});
					}
				});

				// 监听用户取消发布音频流事件
				this.client.on("user-unpublished", (user, mediaType) => {
					if (mediaType === "audio") {
						console.log(`远程用户 ${user.uid} 取消了音频流`);
						this.hangUp(user.uid);
						this.isRemoteSpeaking = false;
						this.showVoiceCall = false
					}
				});

				// 监听用户离开事件
				this.client.on("user-left", (user) => {
					console.log(`远程用户 ${user.uid} 已离开`);
					this.isRemoteSpeaking = false;
					this.showVoiceCall = false
					this.hangUp(user.uid);
				});

				// 网络质量检测
				this.client.on("network-quality", (stats) => {
					this.updateNetworkStatus(stats);
				});
			},

			// 发布本地音频流
			async publishAudio() {
				if (!this.client) {
					console.log("请先加入频道");
					return;
				}

				try {
					console.log("正在获取麦克风权限...");

					// 创建本地音频轨道
					this.localAudioTrack = await AgoraRTC.createMicrophoneAudioTrack({
						encoderConfig: "speech_standard", // 语音优化配置
						AEC: true, // 回声消除
						ANS: true // 降噪
					});

					// 设置初始音量
					this.localAudioTrack.setVolume(this.isSpeakerOn ? 100 : 50);

					// 监听本地音频音量变化
					this.localAudioTrack.on("volume-change", (volume) => {
						this.isMuted = volume === 0;
					});

					this.localAudioTrack.on("track-ended", () => {
						console.error("音频轨道意外结束！");
					});

					// 发布本地音频轨道
					console.log("正在发布本地音频流...");
					await this.client.publish([this.localAudioTrack]);
					console.log("本地音频流已发布,本地用户" + this.userInfo.id);

				} catch (error) {
					console.log(`发布音频流失败: ${error.message}`);

					// 发生错误时关闭轨道
					if (this.localAudioTrack) {
						this.localAudioTrack.close();
						this.localAudioTrack = null;
					}

					this.handlePublishError('获取麦克风权限失败');
					this.stopCallTimer();
				}
			},

			// 取消发布本地音频流
			async unpublishAudio() {
				if (!this.client) {
					console.log("客户端未初始化");
					return;
				}

				try {
					console.log("正在取消发布本地音频流...");

					if (this.localAudioTrack) {
						await this.client.unpublish([this.localAudioTrack]);
						this.localAudioTrack.close();
						this.localAudioTrack = null;
					}

					console.log("已取消发布本地音频流");

				} catch (error) {
					console.log(`取消发布失败: ${error.message}`);
					console.error(error);
				}
			},

			// 离开频道
			async leaveChannel() {
				if (!this.client) {
					console.log("客户端未初始化");
					return;
				}

				try {
					console.log("开始挂断流程...");

					// 1. 先取消发布所有轨道
					if (this.localAudioTrack) {
						console.log("取消发布音频轨道...");
						await this.client.unpublish([this.localAudioTrack]);
						this.localAudioTrack.close();
						this.localAudioTrack = null;
					}

					// 2. 然后离开频道
					console.log("离开频道...");
					await this.client.leave();
					this.client = null;

					console.log("挂断流程完成");

				} catch (error) {
					console.error("挂断过程中出错:", error);
					// 即使出错也尝试强制清理
					this.forceCleanup();
					throw error;
				}
			},

			// 强制清理资源
			forceCleanup() {
				if (this.localAudioTrack) {
					try {
						this.localAudioTrack.close();
					} catch (e) {
						console.warn("强制关闭音频轨道时出错:", e);
					}
					this.localAudioTrack = null;
				}

				if (this.client) {
					try {
						this.client.leave();
					} catch (e) {
						console.warn("强制离开频道时出错:", e);
					}
					this.client = null;
				}
			},

			// 清理资源
			cleanup() {
				this.forceCleanup();
				this.stopCallTimer();
			},

			// 处理加入频道错误
			handleJoinError(error) {
				this.$emit('call-action', {
					callerId: "audioCall",
					status: false,
					timestamp: Date.now(),
					userId: this.userInfo.id,
					error: error
				});
			},

			// 处理发布音频错误
			handlePublishError(error) {
				this.$emit('call-action', {
					callerId: "audioCall",
					status: false,
					timestamp: Date.now(),
					userId: this.userInfo.id,
					error: error
				});
			},

			// 更新网络状态显示
			updateNetworkStatus(stats) {
				if (stats.downlinkNetworkQuality > 4) {
					this.showToastMessage('网络较差');
				}
				if (stats.downlinkNetworkQuality > 6) {
					this.showToastMessage('网络非常差');
				}
			},

			// 显示提示消息
			showToastMessage(message) {
				this.toastMessage = message;
				// this.showToast = true;
				setTimeout(() => {
					uni.showToast({
						title: message,
						icon: 'none'
					})
					// this.showToast = false;
				}, 2000);
			}
		}
	};
</script>

<style scoped>
	/* 保留原有的CSS样式，这里只添加scoped属性 */
	.voice-container {
		position: fixed;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		background-color: #1a1a1a;
		color: white;
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		z-index: 1000;
	}

	.remote-avatar {
		width: 180px;
		height: 180px;
		border-radius: 50%;
		overflow: hidden;
		margin-bottom: 30px;
	}

	.remote-avatar img {
		width: 100%;
		height: 100%;
		object-fit: cover;
	}

	.local-avatar {
		position: absolute;
		bottom: 180px;
		right: 20px;
		width: 80px;
		height: 80px;
		border-radius: 50%;
		overflow: hidden;
		border: 2px solid white;
	}

	.local-avatar img {
		width: 100%;
		height: 100%;
		object-fit: cover;
	}

	.call-info {
		text-align: center;
		margin-bottom: 30px;
	}

	.caller-name {
		font-size: 24px;
		font-weight: bold;
		margin-bottom: 10px;
	}

	.call-status {
		font-size: 16px;
		color: #ccc;
	}

	.voice-wave {
		display: flex;
		justify-content: center;
		align-items: center;
		gap: 8px;
		margin-bottom: 40px;
		height: 40px;
	}

	.wave-bar {
		width: 4px;
		height: 20px;
		background-color: #4CAF50;
		border-radius: 2px;
		animation: wave 1s infinite ease-in-out;
	}

	.wave-bar:nth-child(1) {
		animation-delay: 0.1s;
	}

	.wave-bar:nth-child(2) {
		animation-delay: 0.2s;
	}

	.wave-bar:nth-child(3) {
		animation-delay: 0.3s;
	}

	.wave-bar:nth-child(4) {
		animation-delay: 0.4s;
	}

	.wave-bar:nth-child(5) {
		animation-delay: 0.5s;
	}

	@keyframes wave {

		0%,
		100% {
			transform: scaleY(1);
		}

		50% {
			transform: scaleY(2);
		}
	}

	.control-buttons {
		display: flex;
		justify-content: center;
		gap: 40px;
		position: absolute;
		bottom: 60px;
		width: 100%;
	}

	.control-button {
		width: 70px;
		height: 70px;
		border-radius: 50%;
		border: none;
		background-color: rgba(255, 255, 255, 0.1);
		color: white;
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		cursor: pointer;
		transition: all 0.3s;
	}

	.control-button img {
		width: 24px;
		height: 24px;
		margin-bottom: 5px;
		filter: brightness(0) invert(1);
	}

	.control-button span {
		font-size: 12px;
	}

	.control-button:hover {
		background-color: rgba(255, 255, 255, 0.2);
	}

	.mute.active,
	.speaker.active {
		background-color: rgba(255, 255, 255, 0.3);
	}

	.end-call {
		background-color: #ff3b30;
	}

	.end-call:hover {
		background-color: #ff5e55;
	}

	/* 来电界面样式 */
	/* 来电振动动画 */
	@keyframes vibrate {
		0% {
			transform: rotate(0deg);
		}

		25% {
			transform: rotate(2deg);
		}

		50% {
			transform: rotate(0deg);
		}

		75% {
			transform: rotate(-2deg);
		}

		100% {
			transform: rotate(0deg);
		}
	}

	.incoming-call {
		animation: vibrate 0.3s infinite;
		text-align: center;
	}

	#incoming-call {
		position: fixed;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		background-color: #1a1a1a;
		color: white;
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		z-index: 1000;
	}

	.caller-avatar {
		width: 150px;
		height: 150px;
		border-radius: 50%;
		overflow: hidden;
		margin-bottom: 20px;
	}

	.caller-avatar img {
		width: 100%;
		height: 100%;
		object-fit: cover;
	}

	.call-status {
		font-size: 16px;
		color: #ccc;
		margin-bottom: 40px;
	}

	.answer-buttons {
		display: flex;
		justify-content: center;
		gap: 60px;
	}

	.decline-call,
	.accept-call {
		width: 70px;
		height: 70px;
		border-radius: 50%;
		display: flex;
		align-items: center;
		justify-content: center;
		cursor: pointer;
		transition: all 0.3s;
	}

	.decline-call {
		background-color: #ff3b30;
	}

	.accept-call {
		background-color: #4CAF50;
	}

	.decline-call:hover {
		background-color: #ff5e55;
	}

	.accept-call:hover {
		background-color: #66BB6A;
	}

	.decline-call img,
	.accept-call img {
		width: 30px;
		height: 30px;
		filter: brightness(0) invert(1);
	}

	/* Toast提示样式 */
	.toast {
		position: fixed;
		bottom: 100px;
		left: 50%;
		transform: translateX(-50%);
		background-color: rgba(0, 0, 0, 0.7);
		color: white;
		padding: 12px 24px;
		border-radius: 4px;
		z-index: 1100;
		opacity: 0;
		transition: opacity 0.3s;
	}

	.toast.show {
		opacity: 1;
	}

	.toast.hide {
		opacity: 0;
	}

	.toast-content p {
		margin: 0;
		font-size: 14px;
	}
</style>